package com.appspot.inkisapi;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import com.appspot.inkisapi.entity.BlogPost;
import com.appspot.inkisapi.service.BlogPostService;
import com.appspot.inkisapi.service.LowLevelDatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Text;
import com.google.gson.Gson;

public class SimpleBlogApiServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public static final String POSTS_KIND = "posts";

	@Override
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		String[] pathComponents = request.getRequestURI().split("/");
		if (pathComponents.length <= 2 || (pathComponents.length > 4)) {
			sendError(response, HttpServletResponse.SC_BAD_REQUEST,
					"Bad Request");
			return;
		}
		String kind = pathComponents[2];
		if (!kind.equalsIgnoreCase(POSTS_KIND)){
			sendError(response, HttpServletResponse.SC_BAD_REQUEST,
					"Bad Request");
			return;
		}

		String id = null;
		if (pathComponents.length == 4) {
			id = pathComponents[3];
		}

		// Work out what the HTTP action was
		String verb = request.getMethod();
		if (verb.equals("GET")) {
			handleGet(kind, id, response);
			return;
		} else if (verb.equals("POST")) {
			handlePost(kind, request, response);
			return;
		} else if (verb.equals("DELETE")) {
			if (id == null) {
				sendError(response, HttpServletResponse.SC_BAD_REQUEST,
						"Bad Request");
				return;
			}
			handleDelete(kind, id, response);
			return;
		} else {
			sendError(response, HttpServletResponse.SC_BAD_REQUEST,
					"Bad Request");
			return;
		}
	}

	public void handleGet(String kind, String id, HttpServletResponse response)
			throws IOException, ServletException {
		try {
			if (kind.equalsIgnoreCase(POSTS_KIND)){
				if (id == null) { // get all item of kind
					List<BlogPost> results = BlogPostService.getAllBlogPosts();
					StringBuilder sb = new StringBuilder();
					sb.append("{\"results\":[");
					for (int i=0; i<results.size(); i++){
						Gson gson = new Gson();
						String json = gson.toJson(results.get(i));
						sb.append(json);
						if (i != results.size()-1) {
							sb.append(",");
						}
					}
					sb.append("]}");
					response.setContentType("application/json; charset=utf-8");
					response.addHeader("Access-Control-Allow-Origin", "*");
					response.setStatus(HttpServletResponse.SC_OK);
					response.getWriter().print(sb.toString());
				} else { // get item of kind with key
					Entity entity = LowLevelDatastoreService.getEntity(kind, id);
					if (entity == null) {
						sendError(response, HttpServletResponse.SC_NO_CONTENT,
								"Item Not Found");
					} else {
						Map<String, Object> result = entity.getProperties();
						Text tmp = (Text) result.get("tittle");
						String tittle = tmp.getValue();
						tmp = (Text) result.get("content");
						String content = tmp.getValue();
						StringBuilder sb = new StringBuilder();
						sb.append("{\"results\":[{");
						sb.append("\"tittle\":\"" + tittle + "\",");
						sb.append("\"content\":\"" + content + "\"}");
						sb.append("]}");
						response.setContentType("application/json; charset=utf-8");
						response.addHeader("Access-Control-Allow-Origin", "*");
						response.setStatus(HttpServletResponse.SC_OK);
						response.getWriter().print(sb.toString());
					}
				}
			}
		} catch (Exception ex) {
			sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
					"Exception");
		}
	}

	public void handlePost(String kind, HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		try {
			if (kind.equalsIgnoreCase(POSTS_KIND)){
				String tittle = request.getParameter("tittle");
				String date = request.getParameter("date");
				String content = request.getParameter("content");
				String meta = request.getParameter("meta");
				int status = Integer.parseInt(request.getParameter("status"));
				BlogPost bp = new BlogPost(tittle, date, content, meta, status);
				BlogPostService.addOrUpdateBlogPost(bp);
			}
		} catch (Exception ex) {
			sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
					"Exception");
		}
	}

	public void handleDelete(String kind, String id,
			HttpServletResponse response) throws IOException, ServletException {
		try {
			if (kind.equalsIgnoreCase(POSTS_KIND)){
				BlogPostService.deleteBlogPost(id);
			}
		} catch (Exception ex) {
			sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
					"Exception");
		}
	}

	private void sendError(HttpServletResponse response, int code, String msg)
			throws IOException {
		StringBuilder sb = new StringBuilder();
		sb.append("{\"error\":[");
		sb.append("{\"code\":\"" + code + "\",");
		sb.append("\"message\":\"" + msg + "\"}");
		sb.append("]}");
		response.setContentType("application/json; charset=utf-8");
		response.addHeader("Access-Control-Allow-Origin", "*");
		response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
		response.getWriter().print(sb.toString());
	}

//	private String convertToId(String input) {
//		String ret;
//		ret = input.replaceAll("\\W", "");
//		return ret;
//	}
}
